﻿using System;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;

namespace O1.Data
{
    [ContractVerification(true)]
    [StructLayout(LayoutKind.Explicit)]
    public struct DateProperty : IEquatable<DateProperty>
    {
        public const int Size = Sz.Cell.PropDate;

        [FieldOffset(0)]
        public readonly DateTime Value;

        [FieldOffset(Sz.CLR.DateTime)]
        public readonly int Key;

        public DateProperty(int key, DateTime value)
            : this()
        {
            this.Key = key;
            this.Value = value;
        }

        public static bool operator ==(DateProperty instance, DateProperty other)
        {
            return instance.Equals(other);
        }

        public static bool operator !=(DateProperty instance, DateProperty other)
        {
            return !instance.Equals(other);
        }

        public bool Equals(DateProperty other)
        {
            return this.Key == other.Key && this.Value == other.Value;
        }

        public override int GetHashCode()
        {
            return this.Key.GetHashCode() ^ this.Value.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return false;
            }

            if (obj.GetType() != typeof(DateProperty))
            {
                return false;
            }

            return this.Equals((DateProperty)obj);
        }

        internal static unsafe DateProperty Read(byte[] buffer, int offset)
        {
            Contract.Requires(buffer != null);
            Contract.Requires(0 <= offset);
            Contract.Requires(offset + Size < buffer.Length, ExceptionText.ValueBufferTooSmall);

            fixed (byte* p = &buffer[offset])
            {
                return *((DateProperty*)p);
            }
        }

        internal unsafe void Write(byte[] buffer, int offset)
        {
            Contract.Requires(buffer != null);
            Contract.Requires(0 <= offset);
            Contract.Requires(offset + Size < buffer.Length, ExceptionText.ValueBufferTooSmall);

            fixed (byte* p = &buffer[offset])
            {
                *((DateProperty*)p) = this;
            }
        }
    }
}